package edu.whut.mall.admin.shiro.auth;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;

/**
 * Author: smq
 * Unit: D9lab
 * Description: 正常来讲 Shiro 是从 Cookie 中获取 SessionId 的（session是访问后生成的一个特殊请求，保存在cookie里）
 *              然后找到相对应的 Session 来保证用户登陆的正确性和权限的正确性，但是在前后端分离的项目中，
 *              由于每次的 SessionId 都是不一样的（每次访问都需要发一个请求），所以我这里选择的是重写 DefaultWebSessionManager 的部分方法，
 *              然后在用户登陆的时候给前端返回 SessionId 来当用户的凭证信息（相当于自己制作了一个sessionId，是结合用户名密码制作的）
 *              前端在请求头中携带信息，来解决 Shiro 的用户 Token 认证问题。
 * Date: 2021-06-11 17.40
 */

public class MySessionManager extends DefaultWebSessionManager {
    private static final String AUTHORIZATION = "Authorization";

    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
        //如果请求头中有 Authorization 则其值为sessionId       //前后端分离项目获取SessionId
        if (!StringUtils.isEmpty(id)) {
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
            return id;
        } else {
            //否则按默认规则从cookie取sessionId               //传统项目获取SessionId
//            System.err.println("=============本地从cookie中获取=================" + super.getSessionId(request, response));
//            return super.getSessionId(request, response);
            return false;
        }
    }

}
